package cn.ycc1.boot3csv.service.impl;

import cn.ycc1.boot3csv.entity.Order;
import cn.ycc1.boot3csv.service.TestService;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author ycc
 * @date 2025/11/13
 */
@Slf4j
@Service
public class TestServiceImpl implements TestService {

    @Override
    public void testCSV(String filePath) {
        try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
            List<String[]> allData = reader.readAll();

            // 遍历所有行
            for (String[] row : allData) {
                for (String cell : row) {
                    System.out.print(cell + " | ");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            log.error("处理CSV文件时发生错误", e);
        }
    }

    @Override
    public List<String[]> readSimpleCSV() {
        ClassPathResource resource = new ClassPathResource("simple_data.csv");

        if (!resource.exists()) {
            log.warn("CSV文件不存在: {}", "simple_data.csv");
            return Collections.emptyList();
        }

        // 始终使用try-with-resources来管理需要关闭的资源，这是更安全、更简洁的做法。
        try (InputStream inputStream = resource.getInputStream();
             InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             CSVReader reader = new CSVReaderBuilder(streamReader).build()) {

            return processCSVData(reader.readAll());

        } catch (IOException e) {
            log.error("读取CSV文件时发生IO错误: {}", resource.getFilename(), e);
            throw new RuntimeException("无法读取CSV文件: " + resource.getFilename(), e);
        } catch (CsvException e) {
            log.error("解析CSV文件时发生格式错误: {}", resource.getFilename(), e);
            throw new RuntimeException("CSV文件格式错误: " + resource.getFilename(), e);
        }
    }

    private List<String[]> processCSVData(List<String[]> allData) {
        if (allData.isEmpty()) {
            log.info("CSV文件为空");
            return Collections.emptyList();
        }

        System.out.println("=== 简单CSV数据 ===");

        // 判断是否跳过标题行
        int startRow = allData.size() > 1 && isHeaderRow(allData.get(0)) ? 1 : 0;
        List<String[]> dataRows = new ArrayList<>();

        for (int i = startRow; i < allData.size(); i++) {
            String[] row = allData.get(i);
            dataRows.add(row);

            if (row.length >= 4) {
                System.out.printf("姓名: %s, 年龄: %s, 城市: %s, 工资: %s%n",
                        row[0], row[1], row[2], row[3]);
            } else {
                log.warn("第{}行数据不完整，期望4列，实际{}列", i + 1, row.length);
            }
        }

        System.out.println();
        return dataRows;
    }

    // 辅助方法：判断是否为标题行
    private boolean isHeaderRow(String[] row) {
        if (row.length == 0) return false;
        // 根据实际需求调整判断逻辑
        String firstCell = row[0].toLowerCase();
        return firstCell.contains("姓名") || firstCell.contains("name");
    }

    /**
     * 解析订单数据行
     * @return
     */
    @Override
    public List<Order> readComplexCSV() {
        ClassPathResource resource = new ClassPathResource("complex_data.csv");

        if (!resource.exists()) {
            log.error("CSV文件不存在: complex_data.csv");
            return Collections.emptyList();
        }

        try (InputStream inputStream = resource.getInputStream();
             InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             CSVReader reader = new CSVReaderBuilder(streamReader)
                     .withSkipLines(1) // 跳过标题行
                     .build()) {

            List<String[]> allData = reader.readAll();
            log.info("成功读取CSV文件，共{}行数据", allData.size());

            return processOrderData(allData);

        } catch (IOException e) {
            log.error("读取CSV文件时发生IO错误: {}", resource.getFilename(), e);
            throw new RuntimeException("无法读取CSV文件: " + resource.getFilename(), e);
        } catch (CsvException e) {
            log.error("解析CSV文件时发生格式错误: {}", resource.getFilename(), e);
            throw new RuntimeException("CSV文件格式错误: " + resource.getFilename(), e);
        }
    }

    private List<Order> processOrderData(List<String[]> csvData) {
        List<Order> orders = new ArrayList<>();

        System.out.println("\n=== 复杂数据结构CSV数据 ===");

        for (int i = 0; i < csvData.size(); i++) {
            String[] row = csvData.get(i);

            try {
                if (row.length < 6) {
                    log.warn("第{}行数据不完整，跳过处理: {}", i + 2, String.join(",", row));
                    continue;
                }

                Order order = parseOrderRow(row);
                orders.add(order);

                // 输出格式化信息
                System.out.printf("订单号: %s, 客户: %s, 产品: %s, 日期: %s, 金额: %s, 完成: %s%n",
                        order.getOrderNumber(), order.getCustomerName(),
                        String.join("|", order.getProducts()), order.getOrderDate(),
                        order.getTotalAmount(), order.isCompleted());

            } catch (Exception e) {
                log.error("解析第{}行数据时发生错误: {}", i + 2, String.join(",", row), e);
            }
        }

        return orders;
    }

    private Order parseOrderRow(String[] row) {
        Order order = new Order();
        order.setOrderNumber(row[0]);
        order.setCustomerName(row[1].replace("\"", "")); // 去除引号

        // 解析产品列表
        if (!row[2].isEmpty()) {
            String[] products = row[2].split(",");
            order.setProducts(Arrays.asList(products));
        } else {
            order.setProducts(Collections.emptyList());
        }

        order.setOrderDate(row[3]);

        // 解析金额
        try {
            order.setTotalAmount(Double.parseDouble(row[4]));
        } catch (NumberFormatException e) {
            log.warn("金额格式错误: {}, 使用默认值0.0", row[4]);
            order.setTotalAmount(0.0);
        }

        // 解析完成状态
        order.setCompleted(Boolean.parseBoolean(row[5]));

        return order;
    }

    /**
     * 简化版的读取复杂CSV数据，不进行实体转换
     */
    public void readComplexCSVSimple() {
        ClassPathResource resource = new ClassPathResource("complex_data.csv");

        try (InputStream inputStream = resource.getInputStream();
             InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             CSVReader reader = new CSVReaderBuilder(streamReader)
                     .withSkipLines(1)
                     .build()) {

            List<String[]> allData = reader.readAll();
            System.out.println("\n=== 复杂数据结构CSV数据 ===");

            for (String[] row : allData) {
                if (row.length >= 6) {
                    System.out.printf("订单号: %s, 客户: %s, 产品: %s, 日期: %s, 金额: %s, 完成: %s%n",
                            row[0], row[1], row[2], row[3], row[4], row[5]);
                }
            }

        } catch (IOException e) {
            log.error("读取CSV文件时发生IO错误", e);
        } catch (CsvException e) {
            log.error("解析CSV文件时发生格式错误", e);
        }
    }
}
